#include <iostream>

class Product {
    public:
    virtual ~Product() {}
    virtual std::string Operation() = 0;
};

class ConcreteProductA : public Product {
    public:
    std::string Operation() override {
        return "ConcreteProductA";
    }

};

class ConcreteProductB : public Product {
    public:
    std::string Operation() override {
        return "ConcreteProductB";
    }
};

class Creator {
    public:
    virtual ~Creator() {}
    virtual Product* FactoryMethod() = 0;

    std::string SomeOperation() {
        Product* product = this->FactoryMethod();
        std::string result = product->Operation();
        delete product;
        return result;
    }
};


class ConcreteCreatorA : public Creator {
    public:
    Product* FactoryMethod() override {
        return new ConcreteProductA();
    }
};

class ConcreteCreatorB : public Creator {
    public:
    Product* FactoryMethod() override {
        return new ConcreteProductB();
    }
};


void ClientCode(const Creator& creator) {
    std::cout << "Client:but it still works.\n" << creator.SomeOperation() << std::endl;
}

int main() {
    std::cout << "App: Launched with the ConcreteCreatorA.\n";
    Creator* creator = new ConcreteCreatorA();
    ClientCode(*creator);
    std::cout << "\nApp: Launched with the ConcreteCreatorB.\n";
    creator = new ConcreteCreatorB();
    ClientCode(*creator);
    delete creator;
    return 0;
}